unit RetroPlots;

interface


uses DiagramFactory, datacontainer, pganalysistypesunit, apgabstractunit, classes,
   xmlintf, pgseriesunit, chartaxisunit, ifmmemoryunit, math, sysutils, ifmgdi;


type TRetroType = (rtSSB = 0, rtFMean, rtRecruit);

const c_RetroChartName : array[rtSSB..rtRecruit] of string = ('SSB', 'F Mean', 'Recruit');

type
   RetroChart = class(TasacsChart)
   private
      m_RetroType : TRetroType;
   protected
   public
      function CreateChartAxis(Axis : PgAxisType) : APgChartAxis; override;
      function CreateSeries(AOwner : TComponent; PrimaryChartAxis : APgChartAxis; MetaSeries : APgMetaSeries; XIndex : Integer) : APgSeries; override;
      constructor Create(AOwner : TComponent; ItemNode : IXMLNode; Caption : string; RetroType : TRetroType; datacontainer : TasacsDataContainer); reintroduce;
      property RetroType : TRetroType read m_RetroType;
   end; // RetroChart


   RetroDiagram = class(TasacsDiagram)
   public
      constructor Create(AOwner : TComponent; datacontainer : TasacsDataContainer); reintroduce;
   end;


   RetroSeries = class(PgSeries)
   protected
      function GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double; override;
   end; // RetroSeries

   RetroYearAxis = class(StdYearAxis)
   protected
      function GetNumDimensionElms : Integer; override;
   end; // RetroYearAxis
   

implementation


///////////////////////
// RetroChart


function RetroChart.CreateChartAxis(Axis : PgAxisType) : APgChartAxis;
begin
   case Axis of
      atx:
         Result := RetroYearAxis.Create(Self as IChart, Axis);
   else
      Result := PgChartAxis.Create(Self as IChart, Axis);
   end; // case
end; // RetroChart.CreateChartAxis


function RetroChart.CreateSeries(AOwner : TComponent; PrimaryChartAxis : APgChartAxis; MetaSeries : APgMetaSeries; XIndex : Integer) : APgSeries;
begin
   Result := nil;
   case PrimaryChartAxis.axis of
      atX:
         if Assigned(MetaSeries) then
            Result := RetroSeries.Create(AOwner, PrimaryChartAxis, MetaSeries, XIndex)
         else
            Result := StdYearAxisSeries.Create(AOwner, PrimaryChartAxis, MetaSeries, XIndex);
   end; // case
end; // RetroChart.CreateSeries


constructor RetroChart.Create(AOwner : TComponent; ItemNode : IXMLNode; Caption : string; RetroType : TRetroType; datacontainer : TasacsDataContainer);
var
   M : APgMetaSeries;
   seriesname, YAxisLbl : string;
   I, NumRuns : Integer;
begin
   m_RetroType := RetroType;
   inherited Create(AOwner, ItemNode, 'Chart', datacontainer);
   Self.Caption := Caption;
   ChartLegend := Caption;
   self.ShowChartLegend := true;
   self.ShowSeriesLegend := true;
   if not Assigned(ItemNode) then
   begin
      ShowSeriesLegend := true;
      ShowMeanLegend := false;
//      ChartAxis[atX].ShowIntervalSeries := true;
      PlotType := ptCategorySingle;

      chartaxis[atX].ContinuousGroupData := false;
      chartaxis[atX].ShowMinorTick := false;
      chartaxis[atX].AxisLine := true;
      chartaxis[atX].ShowTickText := true;
      chartaxis[atX].ShowMajorTick := true;
      //chartaxis[atX].AxisLabelPosition := alpCenter;
      chartaxis[atX].ShowMajorGrid := true;
      case RetroType of
         rtSSB: YAxisLbl := 'SSB';
         rtFMean: YAxisLbl := 'F mean';
         rtRecruit: YAxisLbl := 'Recruit';
      end; // case
      chartaxis[aty].ShowLabel := true;
      chartaxis[aty].AxisLabel := YAxisLbl;
      chartaxis[aty].AxisLabelPosition := alpCenter;
      chartaxis[atY].ShowMajorGrid := true;
      chartaxis[aty].ShowMajorTick := true;
      chartaxis[aty].ShowMinorTick := false;
      chartaxis[aty].ShowTickText := true;
      chartaxis[aty].AxisLine := true;
      chartaxis[aty].DefaultAxisLabel := false;
      chartaxis[aty].DefaultMin := false;
      chartaxis[aty].MinValue := 0;
      // Setup meta series at y axis:
      with ChartAxis[atY].MetaSeries do
      begin
         NumRuns := FloatMatrix(datacontainer.StdData[integer(stdRetroSSB) + integer(RetroType)]).GetSize(1);
         for I := 0 to NumRuns - 1 do
         begin
            SeriesName := inttostr(round(FloatMatrix(datacontainer.StdData[integer(stdRetroSSB) + integer(RetroType)])[I, 0]));
            M := TasacsMetaSeries.Create(ChartAxis[aty], nil, SeriesName, I + 1);
            Add(Pointer(M));
            M.BarPlot := false;
            M.Scatter := true;
            M.LinePlot := true;
         end; // for
      end;
   end;
end; // RetroChart.Create


///////////////////////////////
// RetroDiagram


constructor RetroDiagram.Create(AOwner : TComponent; datacontainer : TasacsDataContainer);
begin
   inherited Create(AOwner, nil, '', 'Retrospective plots', '', datacontainer);
   NumDiagramColumns := 2;
   UseDefDiagramColumns := false;
end; // RetroDiagram.Create


///////////////////////////////
// RetroSeries


function RetroSeries.GetInternalValue(I : Integer; SeriesVariable : PgSeriesVariable; MetaSeries : ApgMetaSeries) : Double;
var
   S : Integer;
   M : FloatMatrix;
   F : FloatArray;
begin
   Result := nan;
   S := Self.MetaSeries.ChartAxis.MetaSeries.IndexOf(Pointer(Self.MetaSeries));
   with RetroChart(PrimaryChartAxis.ChartComp).Datacontainer do
   with RetroChart(PrimaryChartAxis.ChartComp) do
   case SeriesVariable of
      svIntervalDelta:
      begin
         M := FloatMatrix(datacontainer.StdData[integer(stdRetroSSB) + integer(RetroType)]);
         Result := M[S, MinCategory + I + 1];
      end
   else
      Result := inherited GetInternalValue(I, SeriesVariable, MetaSeries)
   end; // case
end; // RetroSeries.GetInternalValue



function RetroYearAxis.GetNumDimensionElms : Integer;
begin
   Result := inherited GetNumDimensionElms - 1
end; // RetroYearAxis.GetNumDimensionElms


end.
